package com.gitee.magic.framework.head.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import com.gitee.magic.core.exception.ApplicationException;

/**
 * 日期时间工具类
 * 
 * @author Start
 */
public class TimeUtils {
	
	public static final String YYYY = "yyyy";
	public static final String YYYYMM = "yyyyMM";
	public static final String YYYYMMDD = "yyyyMMdd";
	public static final String HHMMSS = "HHmmss";
	public static final String YYYYMMDDHH = "yyyyMMddHH";
	public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
	public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
	public static final String YYYYMMDDHHMMSS_SSS = "yyyyMMddHHmmssSSS";
	public static final String YYYYMMDDHHMMSS_SSSZ = "yyyyMMddHHmmssSSSZ";
	public static final String YYYYMMDDHHMMSS_Z = "yyyyMMddHHmmssZ";
	
	public static final String YYYYMM_F = "yyyy-MM";
	public static final String YYYYMMDD_F = "yyyy-MM-dd";
	public static final String HHMMSS_F="HH:mm:ss";
	public static final String YYYYMMDDHHMMSS_F = "yyyy-MM-dd HH:mm:ss";
	public static final String YYYYMMDDHHMMSS_SSS_F = "yyyy-MM-dd HH:mm:ss,SSS";
	public static final String YYYYMMDDTHHMMSS_F_Z="yyyy-MM-dd'T'HH:mm:ss'Z'";
	
	public static final String YYYYMMDD_C = "yyyy年MM月dd日";
	public static final String YYYYMMDDHHMMSS_C = "yyyy年MM月dd日 HH时mm分ss秒";

	/**
	 * 取得系统时间
	 */
	public static String getSysTime(String pattern) {
		return formatSysTime(new SimpleDateFormat(pattern));
	}

	/**
	 * 格式化系统时间
	 */
	private static synchronized String formatSysTime(SimpleDateFormat format) {
		return format.format(Calendar.getInstance().getTime());
	}

	public static String format(Date date, String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}

	public static Date getDate(int days) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DAY_OF_MONTH, days);
		return cal.getTime();
	}

	public static Date getHour(int hours) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.HOUR_OF_DAY, hours);
		return cal.getTime();
	}

	public static boolean validTime(String str, String pattern) {
		DateFormat formatter = new SimpleDateFormat(pattern);
		Date date;
		try {
			date = (Date) formatter.parse(str);
		} catch (ParseException e) {
			throw new ApplicationException(e);
		}
		return str.equals(formatter.format(date));
	}

	public static Date format(String str, String pattern) {
		DateFormat formatter = new SimpleDateFormat(pattern);
		try {
			return (Date) formatter.parse(str);
		} catch (ParseException e) {
			throw new ApplicationException(e);
		}
	}

	public static String getSysYear() {
		return getSysTime(YYYY);
	}

	public static String getSysTime() {
		return getSysTime(YYYYMMDDHHMMSS_F);
	}

	public static String getSysTimeS() {
		return getSysTime(YYYYMMDDHHMMSS_SSS_F);
	}

	public static String getSysTimeLong() {
		return getSysTime(YYYYMMDDHHMMSS);
	}

	public static String getSysTimesLong() {
		return getSysTime(YYYYMMDDHHMMSS_SSS);
	}

	public static String getSysdate() {
		return getSysTime(YYYYMMDD_F);
	}

	public static String getSysyearmonthInt() {
		return getSysTime(YYYYMM);
	}

	public static String getSysdateInt() {
		return getSysTime(YYYYMMDD);
	}

	public static String getSysdateTimeStart() {
		return getSysdate() + " 00:00:00";
	}

	public static String getSysdateTimeEnd() {
		return getSysdate() + " 23:59:59";
	}

	public static String getSysDateLocal() {
		return getSysTime(YYYYMMDD_C);
	}

	public static String getTimeFormat(String str) {
		return format(format(str, YYYYMMDDHHMMSS), YYYYMMDDHHMMSS_F);
	}

	public static String getDateFormat(String str) {
		return format(format(str, YYYYMMDDHHMMSS_F), YYYYMMDD_F);
	}

	public static String getDateFormatLocal(String str) {
		return format(format(str, YYYYMMDDHHMMSS_F), YYYYMMDD_C);
	}

	/**
	 * 获取前一天日期格式
	 */
	public static String getTheDayBefore() {
		return format(getDate(-1), YYYYMMDD);
	}


	public static String getDateFormat(int days) {
		return format(getDate(days), YYYYMMDD_F);
	}

	public static String getDateFormatLocal(int days) {
		return format(getDate(days), YYYYMMDD_C);
	}

	public static String getTimeFormatHour(int hours) {
		return format(getHour(hours), YYYYMMDDHHMMSS_F);
	}

	public static Date getHourTime(int hour) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return  calendar.getTime();
	}

	public static Date getHourTime(int hour, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTomorrowHourTime(int hour) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTomorrowHourTime(int hour, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getThismonthTime(int day, int hour, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.DAY_OF_MONTH, day);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getNextmonthTime(int day, int hour, int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.MONTH, 1);
		calendar.set(Calendar.DAY_OF_MONTH, day);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getMinute(int minute) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.MINUTE, minute);
		return calendar.getTime();
	}

	public static Date getSecond(int second) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.SECOND, second);
		return calendar.getTime();
	}

	public static long subtract(String start) throws ParseException {
		return format(getSysTimeS(), YYYYMMDDHHMMSS_SSS_F).getTime() - format(start, YYYYMMDDHHMMSS_SSS_F).getTime();
	}

	public static long subtract(String end, String start) throws ParseException {
		return format(end, YYYYMMDDHHMMSS_SSS_F).getTime() - format(start, YYYYMMDDHHMMSS_SSS_F).getTime();
	}

	public static String getFormatTime(String pattern,String timeZoneFormat) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		format.setTimeZone(TimeZone.getTimeZone(timeZoneFormat));
		return format.format(Calendar.getInstance().getTime());
	}

	public static String formatTime(String str, String strpattern, String pattern, String timeZoneFormat) throws ParseException {
		DateFormat dateFormat = new SimpleDateFormat(strpattern, Locale.ENGLISH);
		Date date = (Date) dateFormat.parse(str);
		SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
		format.setTimeZone(TimeZone.getTimeZone(timeZoneFormat));
		return format.format(date);
	}

	/**
	 * 时间戳转换成日期格式字符串
	 * @param seconds 精确到秒的字符串
	 * @param format
	 * @return
	 */
	public static String timeStampToDate(long seconds, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(new Date(seconds));
	}

	/**
	 * 日期格式字符串转换成时间戳
	 * @param dateStr
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static long dateToTimeStamp(String dateStr, String format) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.parse(dateStr).getTime();
	}

}